﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Derrick.Web
{
    public partial class HttpStreamService : ServiceBase
    {

        public static AppConfig Configuration;

        private static CometServer _cometServer;
        private static WebSocketServer _webSocketServer;

        private static MessageLoop _messageQueueHandler;

        private TraceSwitch _traceSwitch;


        public HttpStreamService()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {

            System.GC.Collect();

            string configfile = "";

            //Set up tracing:
            _traceSwitch = new TraceSwitch("TraceLevelSwitch", "Tracing level of COMET server.");

            Trace.WriteLineIf(_traceSwitch.TraceVerbose, "Derrick COMET service OnStart() called...");

            string cometSleepTimeStr = ConfigurationManager.AppSettings["CometSleepTime"];
            int cometSleepTime = 5000;
            if (!String.IsNullOrEmpty(cometSleepTimeStr))
            {
                cometSleepTime = Int32.Parse(cometSleepTimeStr);
            }
            Thread.Sleep(cometSleepTime);

            try
            {

                if (args.Length == 0)
                {
                    configfile = ConfigurationManager.AppSettings["CometConfig"];
                    if (String.IsNullOrEmpty(configfile))
                    {
                        configfile = "cometbox.conf";
                    }
                }
                else
                {
                    configfile = args[0];
                }

                if (!new FileInfo(configfile).Exists)
                {
                    try
                    {
                        AppConfig.BuildNewConfigFile(configfile);
                    }
                    catch (Exception ex)
                    {
                        Trace.WriteLineIf(_traceSwitch.TraceError, ex.ToString(), "CometService");
                    }
                }

                if (new FileInfo(configfile).Exists)
                {
                    if ((Configuration = AppConfig.LoadConfig(configfile)) == null)
                    {
                        //Console.WriteLine("Error loading configuration.");
                        GracefullyChokeAndDie();
                        return;
                    }
                }
                else
                {
                    //Console.WriteLine("Configuration not found: " + configfile);
                    GracefullyChokeAndDie();
                    return;
                }


                _cometServer = new CometServer(Configuration.CometInterface);
                _webSocketServer = new WebSocketServer(Configuration.WebSocketInterface);
                _messageQueueHandler = new MessageLoop();
                _messageQueueHandler.SendMessageEvent += new MessageLoop.SendMessageEventHandler(_cometServer.BroadcastMessage);
                //_messageQueueHandler.SendMessageEvent += new MessageLoop.SendMessageEventHandler(_webSocketServer.BroadcastMessage);

                Trace.WriteLineIf(_traceSwitch.TraceVerbose, "Derrick COMET service OnStart() completed.");

            }
            catch (Exception ex)
            {
                Trace.WriteLineIf(_traceSwitch.TraceError, ex.ToString());
            }

        }

        protected override void OnStop()
        {
            _cometServer.ShutDown();
            //_webSocketServer.ShutDown();
            GracefullyChokeAndDie();
        }

        static void GracefullyChokeAndDie()
        {
            System.GC.Collect();
            Trace.WriteLine("Gracefully exiting...");
            Trace.Flush();
            Trace.Close();
        }
    }
}
